#include "MsgRounter.h"
#include "Game.h"

MsgRounter::MsgRounter()
{
	//ctor
		m_isServerInit = false;
		m_isClientInit = false;
}

MsgRounter::~MsgRounter()
{
	//dtor
}

void MsgRounter::ServerRounter(Message* _pMsg)
{
	if(!m_isServerInit)
	{
		ServerInit();
	}

	eCmd curCmd = _pMsg->m_cmd;
	Debug::Log(__func__, " curCmd:", (int)curCmd);
	if(this->m_ServerMsgCallMap.count(curCmd)== 0)
	{
		Debug::Error(__func__, " not found in map: ", (int)curCmd);
		return;
	}

	this->m_ServerMsgCallMap[curCmd](_pMsg);
}

void MsgRounter::ServerInit()
{
	ServerAllRegister();
	m_isServerInit = true;
}

void MsgRounter::ClientRounter(Message* _pMsg)
{
	if(!m_isClientInit)
	{
		ClientInit();
	}

	eCmd curCmd = _pMsg->m_cmd;
	Debug::Log(__func__, " curCmd:", (int)curCmd);
	if(this->m_ClientMsgCallMap.count(curCmd)== 0)
	{
		Debug::Log(__func__, " not found in map: ", (int)curCmd);
		return;
	}

	this->m_ClientMsgCallMap[curCmd](_pMsg);
}

void MsgRounter::ClientInit()
{
	ClientAllRegister();
	m_isClientInit = true;
}

// 发送角色数据到客户端 玩家和NPC通用
void SendRoleDataToClient(int _fd, Role* _pRole)
{
	if(_pRole == nullptr)
	{
		Debug::Error(__func__, " _pRole == nullptr");
		return;
	}

	Message Msg(_fd, eCmd::G2C_Role_Data);

	Msg.AddInt(_pRole->m_oid);
	Msg.AddInt(_pRole->m_cfgId);
	Msg.AddInt(_pRole->m_type);

	Msg.AddInt(_pRole->m_hp);
	Msg.AddInt(_pRole->m_countryId);
	Msg.AddInt(_pRole->m_cityId);
	Msg.AddInt(_pRole->m_buildId);
	Msg.AddInt(_pRole->m_jobId);

	Msg.AddInt(_pRole->m_houseId);
	Msg.AddString(_pRole->m_name);
	Msg.AddString(_pRole->m_desc);

	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}

// 主玩家数据 会全部发送Player内的数据
void SendMainPlayerToClient(int _fd, Player* _pPlayer)
{
	if(_pPlayer == nullptr)
	{
		Debug::Error(__func__, " _pPlayer == nullptr");
		return;
	}

	Role* pRole = Game::GetInstance().GetRoleMgr()->GetRole(_pPlayer->m_roleId);
	SendRoleDataToClient(_fd, pRole);

	Message Msg(_fd, eCmd::G2C_MainPlayer_Info);
	Msg.AddInt(_pPlayer->m_oid); 			// 玩家Id
	Msg.AddInt(_pPlayer->m_silver); 		// 身上的铜钱
	Msg.AddInt(_pPlayer->m_diamond); 		// 身上的钻石
	Msg.AddInt(_pPlayer->m_roleId);			// 角色Id

	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}

// 玩家的数据 只会发送 Player中的部分内容
void SendPlayerToClient(int _fd, Player* _pPlayer)
{
//	Message Msg(_fd, eCmd::G2C_Player_Info);
//	Msg.AddInt(_pPlayer->m_oid); 			// 玩家Id
//	Msg.AddInt(_pPlayer->m_roleId); 		// 角色Id
//
//	Message::Send(&Game::GetInstance().GetSock().GetMsgQunue(), &Msg);
}




void OnC2GRoleInfo(Message* _pMsg)
{
	Debug::Log("case::eCmd::C2G_Role_Info:");

	int userId = _pMsg->GetInt();

	// 如果没有找到PlayerId 则询问WorldServer 先不返回
	int playerId = Game::GetInstance().GetPlayerMgr()->GetPlayerIdByUserId(userId, _pMsg->m_fd);
	if(playerId == -1)
	{
		// 如果没有 可能是登录后第一次查询 询问WS
		Message Msg(Game::GetInstance().GetSockClient()->GetFd(), eCmd::G2W_Login_Role_Info);
		Msg.AddInt(userId);
		Message::Send(&Game::GetInstance().GetSockClient()->GetMsgQunue(), &Msg);

		return;
	}

	Message Msg(_pMsg->m_fd, eCmd::G2C_Role_Info);
	Msg.AddInt(playerId);
	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}

void OnC2GRoleCreate(Message* _pMsg)
{
	Debug::Log("case::eCmd::C2G_Role_Create:");
	int roleCfgId = _pMsg->GetInt();
	string playerName = _pMsg->GetString();

	int userId = Game::GetInstance().GetPlayerMgr()->GetUserId(_pMsg->m_fd);
	if(userId == -1)
	{
		int retCode = 2; 		// 0:代表成功  1:代表名称重复, 2:scok_fd链接错误

		Message Msg1(_pMsg->m_fd, eCmd::G2C_Role_Create_Ret);
		Msg1.AddInt(retCode);
		Msg1.AddInt(-1);
		Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg1);
		return;
	}

	Message Msg(Game::GetInstance().GetSockClient()->GetFd(), eCmd::G2W_Player_Create);
	Msg.AddInt(userId);
	Msg.AddInt(roleCfgId);
	Msg.AddString(playerName);
	Message::Send(&Game::GetInstance().GetSockClient()->GetMsgQunue(), &Msg);
}

void OnSYSCheckAnswer(Message* _pMsg)
{
	Debug::Log("case::eCmd::OnSYSCheckAnswer");
	int retKey = _pMsg->GetInt();
	bool isServer = _pMsg->GetBool();

	// 返回key不对， 不是我们程序 关闭链接
	if(retKey != 8259 || isServer)
	{
		Debug::Warn("Not our process, shutdown connect.");
		Game::GetInstance().GetSock()->ShutDownAConnect(_pMsg->m_fd);
		return;
	}

	Client* pClient = Game::GetInstance().GetSock()->GetClient(_pMsg->m_fd);
	if(pClient == nullptr)
	{
		Debug::Error("Not found Client in socket");
		return;
	}

	// 链接的socket客户端通过验证
	pClient->m_isPassCheck = true;
}


void OnC2GMainPlayerInfo(Message* _pMsg)
{
	Debug::Log("case::eCmd::C2G_MainPlayer_Info");
	int fd = _pMsg->m_fd;
	int playerId = _pMsg->GetInt();

	Player* pPlayer = Game::GetInstance().GetPlayerMgr()->GetPlayerByFd(fd);
	SendMainPlayerToClient(fd, pPlayer);
}



void OnSYSCheckAsk(Message* _pMsg)
{
	int key = _pMsg->GetInt();
	if(key != 9527)
	{
		Debug::Error("key Error ???");
		return;
	}

	int retKey = 8259;
	bool isServer = true;

	Message Msg(Game::GetInstance().GetSockClient()->GetFd(), eCmd::SYS_Check_Answer);
	Msg.AddInt(retKey);
	Msg.AddBool(isServer);
	Message::Send(&Game::GetInstance().GetSockClient()->GetMsgQunue(), &Msg);
}

void OnW2GLoginInfo(Message* _pMsg)
{
	Login* pLoginData = Game::GetInstance().GetLogin();
	int id = pLoginData->m_GameServerInfo.m_id;
	string serverName = pLoginData->m_GameServerInfo.m_name;
	int clientCount = pLoginData->m_GameServerInfo.m_count;
	string loginIp = pLoginData->m_GameServerInfo.m_ip;
	int loginPort =  pLoginData->m_GameServerInfo.m_port;

	Message Msg(Game::GetInstance().GetSockClient()->GetFd(), eCmd::G2W_Login_Info);
	Msg.AddInt(id);
	Msg.AddString(serverName);
	Msg.AddInt(clientCount);
	Msg.AddString(loginIp);
	Msg.AddInt(loginPort);
	Message::Send(&Game::GetInstance().GetSockClient()->GetMsgQunue(), &Msg);
}

void ParseRoleFromMsg(Role& _Role, Message* _pMsg)
{
	_Role.m_oid = _pMsg->GetInt();
	_Role.m_cfgId = _pMsg->GetInt();
	_Role.m_type = _pMsg->GetInt();
	_Role.m_lv = _pMsg->GetInt();
	_Role.m_exp = _pMsg->GetInt();

	_Role.m_hp = _pMsg->GetInt();
	_Role.m_countryId = _pMsg->GetInt();
	_Role.m_cityId = _pMsg->GetInt();
	_Role.m_buildId = _pMsg->GetInt();
	_Role.m_jobId = _pMsg->GetInt();

	_Role.m_houseId = _pMsg->GetInt();
	_Role.m_name = _pMsg->GetString();
	_Role.m_desc = _pMsg->GetString();
}

void ParsePlayerFromMsg(Player& _Player, Message* _pMsg)
{
	_Player.m_oid = _pMsg->GetInt();
	_Player.m_uid = _pMsg->GetInt();
	_Player.m_silver = _pMsg->GetInt();
	_Player.m_diamond = _pMsg->GetInt();

	Role newRole;
	ParseRoleFromMsg(newRole, _pMsg);
	Game::GetInstance().GetRoleMgr()->UpdateRole(newRole);

	_Player.m_roleId = newRole.m_oid;
}


void OnW2GLoginRoleInfo(Message* _pMsg)
{
	Debug::Log(__func__);
	int userId = _pMsg->GetInt();
	int playerId = _pMsg->GetInt();

	int fd = Game::GetInstance().GetPlayerMgr()->GetUserFd(userId);

	// 如果是-1则 没有创建该玩家 否则的 应该创建玩家数据到内存
	if(playerId > 0)
	{
		// 如果有数据 更新到内存中
		Game::GetInstance().GetPlayerMgr()->UpdateFDID(fd, playerId);

		Player newPlayer;
		ParsePlayerFromMsg(newPlayer, _pMsg);
		Game::GetInstance().GetPlayerMgr()->UpdatePlayer(newPlayer);
	}


	Message Msg(fd, eCmd::G2C_Role_Info);
	Msg.AddInt(playerId);
	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg);
}

void OnW2GPlayerCreate(Message* _pMsg)
{
	int userId = _pMsg->GetInt();
	int retCode = _pMsg->GetInt();
	int playerId = _pMsg->GetInt();

	int fd = Game::GetInstance().GetPlayerMgr()->GetUserFd(userId);

	// 如果创建成功了 添加到内存中
	if(playerId > 0)
	{
		// 如果有数据 更新到内存中
		Game::GetInstance().GetPlayerMgr()->UpdateFDID(fd, playerId);

		Player newPlayer;
		ParsePlayerFromMsg(newPlayer, _pMsg);
		Game::GetInstance().GetPlayerMgr()->UpdatePlayer(newPlayer);
	}

	Message Msg1(fd, eCmd::G2C_Role_Create_Ret);
	Msg1.AddInt(retCode);
	Msg1.AddInt(playerId);
	Message::Send(&Game::GetInstance().GetSock()->GetMsgQunue(), &Msg1);
}


void MsgRounter::ServerAllRegister()
{
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::C2G_Role_Info, 				OnC2GRoleInfo));
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::C2G_Role_Create, 				OnC2GRoleCreate));
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::SYS_Check_Answer, 			OnSYSCheckAnswer));
	m_ServerMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::C2G_MainPlayer_Info, 			OnC2GMainPlayerInfo));

}

void MsgRounter::ClientAllRegister()
{
	m_ClientMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::SYS_Check_Ask, 				OnSYSCheckAsk));
	m_ClientMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::W2G_Login_Info, 				OnW2GLoginInfo));
	m_ClientMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::W2G_Login_Role_Info, 			OnW2GLoginRoleInfo));
	m_ClientMsgCallMap.insert(pair<eCmd, pFunc>(eCmd::W2G_Player_Create, 			OnW2GPlayerCreate));

}






